package com.wo.cloud.filter;

import com.wo.cloud.entity.SysUser;
import com.wo.cloud.entity.User;
import com.wo.cloud.security.TokenManager;
import com.wo.cloud.util.Response;
import com.wo.cloud.util.ResponseUtil;
import com.wo.cloud.util.WoCloudConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liry
 * @version 1.0
 * @date Created on 2021/4/18 23:31
 * Description: 认证过滤器， 重写三个方法
 */


public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    private RedisTemplate redisTemplate;
    private TokenManager tokenManager;
    private AuthenticationManager authenticationManager;

    @Autowired
    public TokenLoginFilter(RedisTemplate redisTemplate,
                            TokenManager tokenManager,
                            AuthenticationManager authenticationManager){
        this.redisTemplate = redisTemplate;
        this.tokenManager = tokenManager;
        this.authenticationManager = authenticationManager;
    }


    // form表单提交用户和密码
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>()));
    }

    // 认证成功之后调用方法
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {

        // 认证成功， 得到认证之后的用户信息
        SysUser user = (SysUser) authResult.getPrincipal();

        // 生成token
        String token = tokenManager.createToken(user.getUsername());

        // 将用户名和用户权限存储到redis中
        redisTemplate.opsForValue().set(user.getUsername(), user.getAuthorities());

        // 返回token
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        ResponseUtil.out(response, Response.data(tokenMap));
    }

    // 认证失败之后调用方法
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
                                              HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {

        // 返回认证失败
        ResponseUtil.out(response, Response.fail("认证失败"));
    }
}
